using System;
using System.ComponentModel;
using System.Threading;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;

namespace DP.Sharepoint.Workflow
{
    /// <summary>
    /// starts a workflow associated with a list
    /// </summary>
    public class StartAnotherWorkflow : Activity
    {
        public static DependencyProperty __ContextProperty = DependencyProperty.Register("__Context",
                                                                                         typeof (WorkflowContext),
                                                                                         typeof (StartAnotherWorkflow));


        public static DependencyProperty ListIdProperty = DependencyProperty.Register("ListId", typeof (string),
                                                                                      typeof (StartAnotherWorkflow));

        public static DependencyProperty ListItemProperty = DependencyProperty.Register("ListItem", typeof (int),
                                                                                        typeof (StartAnotherWorkflow));

        public static DependencyProperty WorkflowIdentifierProperty = DependencyProperty.Register("WorkflowIdentifier",
                                                                                                  typeof (string),
                                                                                                  typeof (
                                                                                                      StartAnotherWorkflow
                                                                                                      ));

        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public WorkflowContext __Context
        {
            get { return ((WorkflowContext) (base.GetValue(__ContextProperty))); }
            set { base.SetValue(__ContextProperty, value); }
        }

        [Description("ID of the list we are working with")]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string ListId
        {
            get { return ((string) (base.GetValue(ListIdProperty))); }
            set { base.SetValue(ListIdProperty, value); }
        }

        [Description("ID of the list item we are working with")]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int ListItem
        {
            get { return ((int) (base.GetValue(ListItemProperty))); }
            set { base.SetValue(ListItemProperty, value); }
        }

        [Description("Workflow name or template base id")]
        [ValidationOption(ValidationOption.Required)]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string WorkflowIdentifier
        {
            get { return ((string) (base.GetValue(WorkflowIdentifierProperty))); }
            set { base.SetValue(WorkflowIdentifierProperty, value); }
        }

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            try
            {
                //need to run under SHAREPOINT\system account because workflow owner might not have start workflow permissions on the target list
                SPSecurity.RunWithElevatedPrivileges(delegate
                                                         {
                                                             using (SPSite site = new SPSite(__Context.Site.ID))
                                                             {
                                                                 using (SPWeb web = site.AllWebs[__Context.Web.ID])
                                                                 {
                                                                     SPList list = web.Lists[new Guid(ListId)];

                                                                     SPListItem listItem =
                                                                         list.Items.GetItemById(ListItem);

                                                                     //resolve any lookup parameters
                                                                     string wkId =
                                                                         Common.ProcessStringField(executionContext,
                                                                                                   WorkflowIdentifier);

                                                                     //find workflow association by name
                                                                     SPWorkflowAssociation myWorkflowAssoc =
                                                                         list.WorkflowAssociations.GetAssociationByName(
                                                                             wkId, Thread.CurrentThread.CurrentCulture);

                                                                     if (myWorkflowAssoc != null)
                                                                     {
                                                                         //start the workflow
                                                                         site.WorkflowManager.StartWorkflow(listItem,
                                                                                                            myWorkflowAssoc,
                                                                                                            myWorkflowAssoc
                                                                                                                .
                                                                                                                AssociationData);
                                                                     }
                                                                 }
                                                             }
                                                         });
            }
            catch (Exception e)
            {
                Common.LogExceptionToWorkflowHistory(e, executionContext, WorkflowInstanceId);

                throw;
            }

            return ActivityExecutionStatus.Closed;
        }
    }
}